home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / drivers / mscdex / testdrv / tests.c < prev   
Encoding:
C/C++ Source or Header  |  1992-01-26  |  57.8 KB  |  1,962 lines

  1. /* FILE: tests.c
  2. **
  3. ** Copyright 1990 by Microsoft, All Rights Reserved.
  4. ** 
  5. ** of TESTDRV.EXE
  6. **
  7. ** Device Driver Test for MSCDEX compatible CD-ROM.
  8. ** Tests most aspects of direct driver requests detailed
  9. ** in Document 000080010-100-O00-1186 Microsoft Device
  10. ** Driver Specification.
  11. **
  12. ** NOTES: The test procedures
  13. **        
  14. ** HISTORY:
  15. **      Created 9/1/90 - JYG
  16. **      10/01/90 Final (v1.0) -by- JYG
  17. ** 12/06/91 Revision Siddhartha Roy
  18. ** 
  19. */
  20.  
  21.  
  22. #include<time.h>
  23. #include<fcntl.h>
  24. #include<string.h>
  25. #include"test.h"
  26.  
  27. //
  28. // Default Control Files
  29. //
  30. #define NUM_ARCHIVES        4
  31.  
  32. static char *szArc[] = {
  33.     "SBC.BIN",
  34.     "BOOKS.BIN",
  35.     "MSPL11.BIN",
  36.     "MSPL.BIN"
  37. };
  38. char * szTesting = "TESTING";
  39.  
  40. //
  41. // Request structures for message reporting
  42. //
  43.  
  44. // 
  45. // Local Messages
  46. //
  47.  
  48. static char *szLocalMsgs [3] = {
  49.     "Attempt this request",
  50.     "Attempt this test",
  51.     "Does not return DRIVE NOT READY"
  52. };
  53.  
  54. /*
  55. ** TestReservedCmd(Dev_List *)
  56. ** - These should all promptly return an UNKNOWN COMMAND Error
  57. ** - Some requests are added if the fWrite flag is FALSE
  58. **
  59. ** Explanation:
  60. **      In this series of tests, we loop over all reserved commands.
  61. **      We have not made concessions for vendor specific commands.
  62. **      
  63. */
  64.  
  65. void    TestReservedCmd(drv)
  66. Dev_List * drv;
  67. {
  68.     extern FLAG fWriteMedia, fInteract, fVerbose;
  69.  
  70.     //
  71.     // array of unsupported driver requests
  72.     //
  73.         
  74.     static BYTE mplUnSupCmd[] = {   
  75.         0x01,0x02,0x04,0x05,0x06,0x08,0x09,
  76.         0x0A,0x0F,0x10,0x81,0x0B,0x86,0x87
  77.     };
  78.     static char szMsg1[] = "No Error Returned";
  79.     static char szMsg2[] = "Attempt these requests";
  80.  
  81.     ReqName sLabel;
  82.     WORD wStatus;
  83.     int j;
  84.  
  85.     //
  86.     // Testing IOCTLI reserved Requests
  87.     //
  88.         
  89.     printf( "\n\n[Testing Reserved Requests]\n" );
  90.     
  91.     if ( fInteract && !Ask( szMsg2 ) ) 
  92.         return;
  93.  
  94.     //
  95.     // Testing codes 0x02, 0x10 - 0xff
  96.     //
  97.     ReportMsg( mRequests[rIRESERVED],"Request Codes 0x02, 0x10 - 0xff" );
  98.  
  99.     if ( !fInteract || Ask( szMsg2 ) )
  100.     {
  101.         sLabel = mRequests[rIRESERVED];
  102.         sLabel.bSubCmd = 2;
  103.         
  104.         StatusTest( wStatus,WDvRqIoiSimple( drv,0x02 ), sLabel );
  105.         
  106.         if ( !(UNKNOWN_CMD&wStatus) )
  107.             ErrorTest( wStatus,sLabel );
  108.         else if ( !(ERRORBIT&wStatus) )
  109.             ErrMsg( sLabel,szMsg1 );
  110.  
  111.         for( j=0x10;j<0xff;j++ )
  112.         {
  113.             sLabel.bSubCmd = (BYTE)j;
  114.             StatusTest( wStatus,WDvRqIoiSimple( drv,(BYTE)j ),sLabel );
  115.         
  116.             if ( !(ERRORBIT&wStatus) )
  117.                 ErrMsg( sLabel,szMsg1 );
  118.             else if ( !(UNKNOWN_CMD & wStatus) )
  119.                 ErrorTest( wStatus,sLabel );
  120.         }
  121.     }
  122.  
  123.     //
  124.     // IOCTLO reserved Requests 0x06 - 0xff
  125.     //
  126.         
  127.     ReportMsg( mRequests[rORESERVED],"Request Codes 0x06 - 0xff" );
  128.  
  129.     if ( !fInteract || Ask( szMsg2 ) )
  130.     {
  131.         for( j=0x06;j<=0xff;j++ )
  132.         {
  133.             sLabel = mRequests[rORESERVED];
  134.             sLabel.bSubCmd = (BYTE)j;
  135.             
  136.             StatusTest( wStatus,WDvRqIooSimple( drv,(BYTE)j ),sLabel );
  137.             if ( !(ERRORBIT & wStatus) )
  138.                 ErrMsg( sLabel,szMsg1 );
  139.             else if ( !(UNKNOWN_CMD & wStatus) )
  140.                 ErrorTest( wStatus,sLabel );
  141.         }
  142.     }
  143.     
  144.     //
  145.     // Device request reserved Requests
  146.     // Tests all reserved Requests in mplUnSupCmd
  147.     //
  148.  
  149.     printf( "\nx\t\tReserved Requests: " );
  150.     
  151.     printf( "\n\t\t0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x",mplUnSupCmd[0],
  152.         mplUnSupCmd[1],mplUnSupCmd[2],mplUnSupCmd[3],mplUnSupCmd[4] );
  153.     printf( "\n\t\t0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x",mplUnSupCmd[5],
  154.         mplUnSupCmd[6],mplUnSupCmd[7],mplUnSupCmd[8],mplUnSupCmd[9] );
  155.     printf( "\n\t\t0x%.2x, 0x%.2x",mplUnSupCmd[10],mplUnSupCmd[11] );
  156.     if ( !fWriteMedia )
  157.         printf( ", 0x%.2x, 0x%.2x",mplUnSupCmd[12],mplUnSupCmd[13] );
  158.  
  159.     if ( !fInteract || Ask( szMsg2 ) )
  160.     {
  161.         //
  162.         // If Non-Writable media, do all tests
  163.         //
  164.             
  165.         j=(fWriteMedia)?11:13;
  166.         do
  167.         {
  168.             sLabel = mRequests[rRESERVED];
  169.             sLabel.bSubCmd = mplUnSupCmd[j];
  170.  
  171.             StatusTest( wStatus,WDvRqSimple( drv,mplUnSupCmd[j--] ),sLabel );
  172.             if ( !(ERRORBIT & wStatus) )
  173.                 ErrMsg( sLabel,szMsg1 );
  174.             else if ( !(UNKNOWN_CMD & wStatus) )
  175.                 ErrorTest( wStatus,sLabel );
  176.         }
  177.         while (j>=0);
  178.     }
  179.  
  180.     //
  181.     // Test Requests 0x11-0x80
  182.     //
  183.         
  184.     printf( "\nx\t\tReserved Requests: 0x11 - 0x80" );
  185.     
  186.     if ( !fInteract || Ask( szMsg2 ) )
  187.     {
  188.         for( j=0x11;j<0x80;j++ )
  189.         {
  190.             sLabel = mRequests[rRESERVED];
  191.             sLabel.bSubCmd = (BYTE)j;
  192.             StatusTest( wStatus,WDvRqSimple( drv,(BYTE) j ),sLabel );
  193.             
  194.             if ( !(ERRORBIT & wStatus) )
  195.                 ErrMsg( sLabel,szMsg1 );
  196.             else if ( !(UNKNOWN_CMD & wStatus) )
  197.                 ErrorTest( wStatus,sLabel );
  198.         }
  199.     }
  200.     printf( "\n\n[End of Reserved Request Testing]\n" );
  201.  
  202. }
  203.  
  204.  
  205. /*
  206. ** TestDrvBytes(Dev_List *)
  207. ** - Hex dump of DrvBytes
  208. ** - Prompts the user if there is redundant information
  209. */
  210.  
  211. void TestDrvBytes( drv )
  212. Dev_List    *drv;
  213. {
  214.     extern FLAG fInteract,fVerbose;
  215.     extern WORD cwSkipped;
  216.     
  217.     DrvBytes_Rec dbrec,olddbrec;
  218.     WORD wStatus;
  219.     
  220.     ReportMsg( mRequests[rIDRVBYTES],"" );
  221.     if ( !fInteract || Ask( szLocalMsgs[0] ) )
  222.         do
  223.         {
  224.             StatusTest( wStatus,WDvRqIoiDrvBytes( drv,&dbrec ),
  225.                 mRequests[rIDRVBYTES] );
  226.  
  227.             if ( dbrec.nbytes > 0x80 )
  228.                 ErrMsg( mRequests[rIDRVBYTES],"data exceeds 128 bytes" );
  229.  
  230.             //
  231.             // pretty print the buffer
  232.             //
  233.  
  234.             /*
  235.             **  The hexdump is currently de-activated.  It can be activated
  236.             **  for more verbose modes.
  237.             */
  238.     
  239.             // HexDump( dbrec.buf,dbrec.nbytes );    
  240.         
  241.             if ( dbrec.nbytes < 0x80 )
  242.                 break;
  243.  
  244.             if ( !fInteract && !memcmp( dbrec.buf,olddbrec.buf,dbrec.nbytes ) )
  245.             {
  246.                 ReportMsg( mRequests[rIDRVBYTES],"Redundant information." );
  247.                 break;
  248.             }
  249.  
  250.             if ( fInteract && !Ask( "Continue" ) )
  251.                 break;
  252.  
  253.             olddbrec = dbrec;
  254.         }
  255.         //
  256.         //  128bytes indicates more information coming
  257.         //
  258.         while ( dbrec.nbytes == 0x80 ); 
  259.             
  260.     else cwSkipped++;
  261. }
  262.  
  263.  
  264. /*
  265. ** TestSectorSize(Dev_List *)
  266. ** - Tests Sector Size for conformance to spec
  267. */
  268.  
  269. void TestSectorSize( drv )
  270. Dev_List    *drv;
  271. {
  272.     extern FLAG fInteract,fVerbose,fRaw;
  273.     extern WORD cwSkipped;
  274.     WORD wSize,wStatus;
  275.     
  276.     ReportMsg( mRequests[rISECTSIZE],"" );
  277.     if ( fInteract && !Ask( szLocalMsgs[1] ) )
  278.     {
  279.         cwSkipped++;
  280.         return;
  281.     }
  282.  
  283.     StatusTest( wStatus,WDvRqIoiSectSize( drv,RAW_MODE,&wSize ),
  284.         mRequests[rISECTSIZE] );
  285.     
  286.     if ( fRaw && !(ERRORBIT&ErrorTest( wStatus,mRequests[rISECTSIZE] )) )
  287.     {
  288.         ReportMsg( mRequests[rISECTSIZE],"Raw size = " );
  289.         printf( "%u",wSize );
  290.         if ( wSize != RAW_SECTOR_SIZE )
  291.             ErrMsg( mRequests[rISECTSIZE],"Returns Bad Raw Sector Size" );
  292.     }
  293.     
  294.     StatusTest( wStatus,WDvRqIoiSectSize( drv,COOKED_MODE,&wSize ),
  295.         mRequests[rISECTSIZE] );
  296.     
  297.     if ( ERRORBIT&ErrorTest( wStatus,mRequests[rISECTSIZE] ) )
  298.         return;
  299.     
  300.     ReportMsg( mRequests[rISECTSIZE],"Cooked size = " );
  301.     printf( "%u",wSize );
  302.     
  303.     if ( wSize != COOKED_SECTOR_SIZE ) 
  304.     {
  305.         ReportMsg( mRequests[rISECTSIZE],"Cooked size = " );
  306.         printf( "%u",wSize );
  307.         
  308.         if ( wSize != COOKED_SECTOR_SIZE )
  309.             ErrMsg( mRequests[rISECTSIZE],"Returns Bad Cooked Sector Size" );
  310.     }
  311. }
  312.  
  313.  
  314. /*
  315. ** TestAudioCtrl(Dev_List *)
  316. ** - Tests the audio capabilities of the player.
  317. ** - Manipulates the channels by switching the mappings
  318. **   and varying the volume levels
  319. **
  320. **  left1 (0)   right1 (1)
  321. **  left2 (2)   right2 (3)
  322. */
  323.  
  324. /*
  325. ** This test can be expanded to make the playing of music
  326. ** more interactive, and if failures occur with muting or
  327. ** controlling volume properly, they can be correctly logged
  328. ** as errors.
  329. */
  330.  
  331.  
  332.  
  333. void TestAudioCtrl(drv)
  334. Dev_List    *drv;
  335. {
  336.     extern  FLAG fAudio, fAudCtrl,fVerbose,fInteract;
  337.     extern  WORD cwAudioChan;
  338.     
  339.     WORD    wStatus;
  340.     AudInfo_Rec ainfoSnd,ainfoRcv;
  341.  
  342.     //
  343.     // default settings
  344.     // chan:    input:      volume:
  345.     //  0           0           0xff
  346.     //  1           1           0xff
  347.     //  2           2           0x00
  348.     //  3           3           0x00
  349.     //
  350.         
  351.     static  AudInfo_Rec ainfoPri = {    
  352.         0x04,0x00,0xff,0x01,0xff,
  353.         0x02,0x00,0x03,0x00
  354.     };
  355.  
  356.     mRequests[rOAUDINFO] = mRequests[rOAUDINFO];
  357.     
  358.     if ( fAudio && fAudCtrl && (!fInteract || 
  359.         Ask( "Attempt audio control requests" )) )
  360.     {
  361.         StatusTest( wStatus,WDvRqIoiAudInfo( drv,&ainfoRcv ),
  362.             mRequests[rIAUDINFO] );
  363.  
  364.         ErrorTest( wStatus,mRequests[rIAUDINFO] );
  365.  
  366.         if ( !(ERRORBIT&wStatus) && fVerbose )
  367.             PrintAudInfo( ainfoRcv );
  368.  
  369.         if ( !(BUSYBIT&wStatus) )
  370.             WarningMsg( mRequests[rIAUDINFO],"Busybit status not set" );
  371.  
  372.         //
  373.         // *** turn off left1 channel
  374.         //
  375.             
  376.         ReportMsg( mRequests[rOAUDINFO],"Channel 0 off, Channel 1 full volume" );
  377.         
  378.         ainfoSnd = ainfoRcv;    
  379.         ainfoSnd.vol1 = 0xff;
  380.         ainfoSnd.vol0 = 0x00;
  381.         
  382.         StatusTest( wStatus,WDvRqIooAudInfo( drv,&ainfoSnd ),
  383.             mRequests[rOAUDINFO] );
  384.     
  385.         ErrorTest( wStatus,mRequests[rOAUDINFO] );
  386.         
  387.         if ( fInteract )
  388.         {
  389.             if ( Ask( "Is channel 0 mute" ) )
  390.                 ReportMsg( mRequests[rOAUDINFO],"Correctly mutes channel 0" );
  391.             else
  392.                 ErrMsg( mRequests[rOAUDINFO],"Fails to mute channel 0" );
  393.         }
  394.         
  395.         StatusTest( wStatus,WDvRqIoiAudInfo( drv,&ainfoRcv ),
  396.             mRequests[rIAUDINFO] );
  397.         
  398.         if ( !(ERRORBIT&ErrorTest( wStatus,mRequests[rIAUDINFO] )) )
  399.         {
  400.             PrintAudInfo( ainfoRcv );
  401.  
  402.             if ( !AINFEQU( ainfoRcv,ainfoSnd ) )
  403.                 ErrMsg( mRequests[rIAUDINFO],"Audio control request failed" );
  404.         }
  405.         
  406.         //
  407.         // *** turn off right1 
  408.         //
  409.             
  410.         ReportMsg( mRequests[rOAUDINFO],"Channel 0 full volume, Channel 1 off" );
  411.         
  412.         ainfoSnd.vol1 = 0x00;       // turn off right1 channel
  413.         ainfoSnd.vol0 = 0xff;       // turn on left1 channel
  414.  
  415.         StatusTest( wStatus,WDvRqIooAudInfo( drv,&ainfoSnd ),mRequests[rOAUDINFO] );
  416.         ErrorTest( wStatus,mRequests[rOAUDINFO] );
  417.         
  418.         if ( fInteract )
  419.         {
  420.             if ( Ask( "Is channel 1 mute" ) )
  421.                 ReportMsg( mRequests[rOAUDINFO],"Correctly mutes channel 1" );
  422.             else
  423.                 ErrMsg( mRequests[rOAUDINFO],"Fails to mute channel 1" );
  424.         }
  425.         
  426.         StatusTest( wStatus,WDvRqIoiAudInfo( drv,&ainfoRcv ),
  427.             mRequests[rIAUDINFO] );
  428.         
  429.         if ( !(ERRORBIT&ErrorTest( wStatus,mRequests[rIAUDINFO] )) )
  430.         {
  431.             PrintAudInfo( ainfoRcv );
  432.             if ( !AINFEQU( ainfoRcv,ainfoSnd ) )
  433.                 ErrMsg( mRequests[rOAUDINFO],"Audio control request failed" );
  434.         }
  435.  
  436.         //
  437.         // ***  Swapping Channel 0 and 1
  438.         //
  439.             
  440.         ReportMsg( mRequests[rOAUDINFO],"Swapping channel 0 and channel 1 inputs" );
  441.         
  442.         ainfoSnd.vol1 = 0xff;       // turn on right1 channel
  443.  
  444.         ainfoSnd.in0 = 0x01;        // swap left1 and right1 channels
  445.         ainfoSnd.in1 = 0x00;
  446.  
  447.         StatusTest( wStatus,WDvRqIooAudInfo( drv,&ainfoSnd ),
  448.             mRequests[rOAUDINFO] );
  449.         ErrorTest( wStatus,mRequests[rOAUDINFO] );
  450.         
  451.         StatusTest( wStatus,WDvRqIoiAudInfo( drv,&ainfoRcv ),
  452.             mRequests[rIAUDINFO] );
  453.                 
  454.         if ( !(ERRORBIT&ErrorTest( wStatus,mRequests[rIAUDINFO] )) )
  455.         {
  456.             PrintAudInfo( ainfoRcv );
  457.             if ( !AINFEQU( ainfoRcv,ainfoSnd ) )
  458.                 ErrMsg( mRequests[rOAUDINFO],"Audio control request failed" );
  459.         }
  460.  
  461.         //
  462.         // Muting all channels
  463.         //
  464.  
  465.         ReportMsg( mRequests[rOAUDINFO],"Muting all Channels" );
  466.         
  467.         ainfoSnd.vol0 = 0x00;       // turn off right1 channel
  468.         ainfoSnd.vol1 = 0x00;       // turn off right1 channel
  469.         ainfoSnd.vol2 = 0x00;       // turn off right1 channel
  470.         ainfoSnd.vol3 = 0x00;       // turn off right1 channel
  471.  
  472.         StatusTest( wStatus,WDvRqIooAudInfo( drv,&ainfoSnd ),mRequests[rOAUDINFO] );
  473.         ErrorTest( wStatus,mRequests[rOAUDINFO] );
  474.         
  475.         if ( fInteract )
  476.         {
  477.             if ( Ask( "Are all channels  mute" ) )
  478.                 ReportMsg( mRequests[rOAUDINFO],"Correctly mutes all channels " );
  479.             else
  480.                 ErrMsg( mRequests[rOAUDINFO],"Fails to mute all channels " );
  481.         }
  482.         
  483.         StatusTest( wStatus,WDvRqIoiAudInfo( drv,&ainfoRcv ),
  484.             mRequests[rIAUDINFO] );
  485.         
  486.         if ( !(ERRORBIT&ErrorTest( wStatus,mRequests[rIAUDINFO] )) )
  487.         {
  488.             PrintAudInfo( ainfoRcv );
  489.             if ( !AINFEQU( ainfoRcv,ainfoSnd ) )
  490.                 ErrMsg( mRequests[rOAUDINFO],"Audio control request failed" );
  491.    }
  492.         
  493.         //
  494.         // *** reset channels
  495.         //
  496.             
  497.         ReportMsg( mRequests[rOAUDINFO],"Restoring Audio Characteristics" );
  498.  
  499.         StatusTest( wStatus,WDvRqIooAudInfo( drv,&ainfoPri ),
  500.             mRequests[rOAUDINFO] );
  501.         ErrorTest( wStatus,mRequests[rOAUDINFO] );
  502.         
  503.         StatusTest( wStatus,WDvRqIoiAudInfo( drv,&ainfoRcv ),
  504.             mRequests[rIAUDINFO] );
  505.         ErrorTest( wStatus,mRequests[rIAUDINFO] );
  506.  
  507.         if ( !AINFEQU( ainfoRcv,ainfoPri ) )
  508.             ErrMsg( mRequests[rOAUDINFO],"Audio control request failed" );
  509.         
  510.         ReportMsg( mRequests[rOAUDINFO],"Changing channel volume from 0x00 to 0xff" );
  511.  
  512.         ainfoSnd = ainfoPri;
  513.        
  514.         //
  515.         // Restore the original settings
  516.         //
  517.             
  518.         StatusTest( wStatus,WDvRqIooAudInfo( drv,&ainfoPri ),
  519.             mRequests[rOAUDINFO] );
  520.     }
  521. }
  522.  
  523. /*
  524. ** TestSeek(Dev_List *, DWORD, BYTE)
  525. ** - test a seek:
  526. **   We attempt to seek to a sector and monitor the Head Location
  527. **   for movement.  The test ceases when the head is in the requested
  528. **   position OR timeout requirements are met.
  529. */
  530.  
  531. #define MAXWAIT     100
  532. #define MAXTIME     10
  533.  
  534. void TestSeek( drv,lSector,chAddrMode )
  535. Dev_List * drv;
  536. DWORD lSector;
  537. BYTE chAddrMode;
  538. {
  539.     extern FLAG fInteract,fVerbose;
  540.     extern WORD cwSkipped;
  541.     
  542.     WORD    wWait,wTimeOut,wStatus;
  543.     DWORD   dwLoc,dwPrevLoc,dwPrevPrevLoc,dwStartLoc;
  544.     
  545.     ReportMsg( mRequests[rSEEK],"Attempting to seek to " );
  546.     if ( chAddrMode == REDBOOK_ADDRMODE ){
  547.         PrintRed( lSector );
  548.     }
  549.     else
  550.         printf( "%lx",lSector );
  551.     
  552.     if ( fInteract && !Ask( "Attempt seek" ) )
  553.     {
  554.         cwSkipped++;
  555.         return;
  556.     }
  557.    
  558.     StatusTest( wStatus,WDvRqIoiLocHead( drv,chAddrMode,&dwStartLoc ),
  559.         mRequests[rILOCHEAD] );
  560.     ErrorTest( wStatus,mRequests[rILOCHEAD] );
  561.     
  562.     StatusTest( wStatus,WDvRqSeek( drv,lSector,chAddrMode ),
  563.         mRequests[rSEEK] );
  564.     ErrorTest( wStatus,mRequests[rSEEK] );
  565.     
  566.     dwLoc = dwStartLoc;
  567.     dwPrevLoc = dwStartLoc;
  568.     
  569.     
  570.     //
  571.     // In this loop, we check for continuous motion of the drive head
  572.     // If the head is stopped or moves in the reverse direction, the
  573.     // loop will start to time out.
  574.     //
  575.         
  576.     for ( wTimeOut=0,wWait=0;wTimeOut<MAXTIME && dwLoc!=lSector;wWait++ )
  577.     {
  578.         dwPrevPrevLoc = dwPrevLoc;
  579.         dwPrevLoc = dwLoc;
  580.         
  581.         StatusTest( wStatus,WDvRqIoiLocHead( drv,chAddrMode,&dwLoc ),
  582.             mRequests[rILOCHEAD] );
  583.         if ( ERRORBIT&ErrorTest( wStatus,mRequests[rILOCHEAD] ) )
  584.             return;
  585.         
  586.         if ( dwLoc>dwPrevLoc && lSector>dwPrevLoc )
  587.         {
  588.             if ( chAddrMode == REDBOOK_ADDRMODE )
  589.             {
  590.                 printf( "\n\t\tMoved outwards(+) " );
  591.                 PrintRed( RedDiff( dwLoc,dwPrevLoc ) );
  592.                 printf( " Sectors, from  " );
  593.                 PrintRed( dwPrevLoc );
  594.                 printf( " to   ");
  595.                 PrintRed (dwLoc);
  596.             }
  597.             else 
  598.                 printf( "\n\t\tMoved +%lx Sectors %lx",dwPrevLoc-dwLoc,dwLoc );
  599.             if ( dwPrevLoc > dwPrevPrevLoc )
  600.                 wTimeOut = 0;
  601.             else wTimeOut++;
  602.         }
  603.         else if ( dwLoc<dwPrevLoc && lSector<dwPrevLoc )
  604.         {   
  605.             if ( chAddrMode==REDBOOK_ADDRMODE )
  606.             {
  607.                 printf( "\n\t\tMoved inwards(-)" );
  608.                 PrintRed( RedDiff( dwLoc,dwPrevLoc ) );
  609.                 printf( " Sectors, from " );
  610.                 PrintRed( dwPrevLoc );
  611.                 printf( " to   ");
  612.                 PrintRed( dwLoc );
  613.             }
  614.             else 
  615.                 printf( "\n\t\tMoved -%lx Sectors %lx",dwPrevLoc-dwLoc,dwLoc );
  616.             
  617.             if ( dwPrevLoc < dwPrevPrevLoc )
  618.                 wTimeOut = 0;
  619.             else wTimeOut++;
  620.         }
  621.         else wTimeOut++;
  622.     }
  623.  
  624.     if ( chAddrMode==REDBOOK_ADDRMODE )
  625.     {
  626.         printf( "\n\t\tStarting Head Location [REDBOOK] " );
  627.         PrintRed( dwStartLoc );
  628.         printf( "\n\t\tEnding Head Location [REDBOOK] " );
  629.         PrintRed( dwLoc );
  630.     }
  631.     else
  632.     {
  633.         printf( "\n\t\tStarting Head Location %lx [HSG]",
  634.             dwStartLoc );
  635.         printf( "\n\t\tEnding Head Location %lx [HSG]",
  636.             dwLoc );
  637.     }
  638. }
  639.  
  640. /*
  641. ** TestUPCCode(Dev_List *)
  642. ** - Try and locate a UPC code on the disk.  If we find it, we print it out
  643. */
  644.  
  645. /*
  646. ** Since some discs DO NOT have UPC information, they will
  647. ** return errors when attempts to find UPC information.
  648. ** Returned errors can also mean errors with the drivers, to
  649. ** ascertain that the error is with the driver, UPC information
  650. ** can also be acquired through the Q Channel
  651. */
  652.  
  653. void TestUPCCode( drv )
  654. Dev_List * drv;
  655. {
  656.     //
  657.     // IOCTLI UPC Code Test
  658.     //
  659.         
  660.     extern FLAG fUPC,fInteract,fVerbose;
  661.     WORD    wStatus;
  662.     UPCCode_Rec upc;
  663.     
  664.     ReportMsg( mRequests[rIUPCCODE],"" );
  665.     
  666.     if ( !fInteract || Ask( szLocalMsgs[0] ) )
  667.     {
  668.         StatusTest( wStatus,WDvRqIoiUPCCode( drv,&upc ),mRequests[rIUPCCODE] );
  669.         if ( fUPC )
  670.         {
  671.             if ( !(ERRORBIT&wStatus) )
  672.             {
  673.                 if ( upc.ctrl_adr!=2 )
  674.                 {
  675.                     WarningMsg( mRequests[rIUPCCODE],"Control and ADR = " );
  676.                     printf( "%.2x\n",upc.ctrl_adr );
  677.                 }
  678.  
  679.                 ReportMsg( mRequests[rIUPCCODE],"UPC/EAN code " );
  680.  
  681.                 // 13 succesive BCD digits , followed by 12 bits of zero
  682.  
  683.                 printf( "%.2x%.2x%.2x%.2x%.2x%.2x%.2x",upc.upc[0],
  684.                     upc.upc[1],upc.upc[2],upc.upc[3],upc.upc[4],
  685.                     upc.upc[5],upc.upc[6] );
  686.                     
  687.             }
  688.             else if ( SECTOR_NOT_FND&wStatus )
  689.                 ReportMsg( mRequests[rIUPCCODE],"No UPC info OR UPC info missed" );
  690.             else
  691.                 ErrorTest( wStatus,mRequests[rIUPCCODE] );
  692.         }   
  693.         else if ( UNKNOWN_CMD&wStatus )
  694.             ReportMsg( mRequests[rIUPCCODE],"Correctly returns UNKNOWN Request" );
  695.         else 
  696.             ErrMsg( mRequests[rIUPCCODE],"Does not return UNKNOWN Request" );
  697.     }
  698. }
  699.  
  700. /*
  701. ** void TestVolSize(Dev_List *)
  702. ** - Volume Size Test
  703. */
  704.  
  705. /*
  706. ** The volume size can be cross checked by the formula
  707. ** 60*75*min+75*sec + frames 
  708. */
  709.  
  710. void TestVolSize(drv)
  711. Dev_List * drv;
  712. {
  713.     extern FLAG fInteract,fVerbose;
  714.     WORD wStatus;
  715.     DWORD size;
  716.     
  717.     ReportMsg( mRequests[rIVOLSIZE],"" );
  718.     
  719.     if ( !fInteract || Ask( szLocalMsgs[0] ) )
  720.     {
  721.     
  722.         StatusTest( wStatus,WDvRqIoiVolSize( drv,&size ),mRequests[rIVOLSIZE] );
  723.         if ( !(ERRORBIT&wStatus) )
  724.         {
  725.             ReportMsg( mRequests[rIVOLSIZE],"Number of sectors = " );
  726.             printf( "%ld",size );
  727.         }
  728.         else
  729.             ErrorTest( wStatus,mRequests[rIVOLSIZE] );
  730.  
  731.     }
  732. }
  733.  
  734. /*
  735. ** TestAudioDisk(Dev_List)
  736. ** - Calls: IOCTLI - LocHead, DiskInfo, TnoInfo, Qinfo, SubChanInfo, AudStat
  737. ** - Calls: PlayReq, ResumeReq, StopReq
  738. ** - Calls: TestAudioCtrl()
  739. */
  740.  
  741. void TestAudioDisk( drv )
  742. Dev_List *  drv;
  743. {
  744.     extern FLAG fInteract,fVerbose,fAudCtrl,fSubInfo;
  745.     extern DWORD  mplRedSector[];
  746.     extern WORD      cwRedSectors;
  747.     WORD            wStatus;
  748.     DiskInfo_Rec    dinfo;
  749.     TnoInfo_Rec     tno;
  750.     DWORD           loc;
  751.     BYTE            i;
  752.     QchanInfo_Rec   qinfo;
  753.     AudStat_Rec audstatRec;
  754.     
  755.     printf("\n\n[AUDIO TESTS]\n");
  756.     
  757.     if ( fInteract && !Ask( "Is this an Audio Disk" ) )
  758.         return;
  759.  
  760.     StatusTest( wStatus,WDvRqIoiDiskInfo( drv,&dinfo ),mRequests[rIDISKINFO] )
  761.     if ( ERRORBIT&ErrorTest( wStatus,mRequests[rIDISKINFO] ) )
  762.     {
  763.         WarningMsg( mRequests[rIDISKINFO],"Skipping Track Info, Seek requests" );
  764.         WarningMsg( mRequests[rITNOINFO],"Skipping Play, Stop, Resume requests" );
  765.         return;
  766.     }
  767.  
  768.  
  769.     //
  770.     // SEEK to end (the sector before the lead out) and test lochead
  771.     //        
  772.  
  773.         
  774.    // We try to seek to one before since the lead out track points to the first
  775.    // sector the last addresable sector
  776.  
  777.    ReportMsg( mRequests[rIDISKINFO],"" );
  778.    printf( "lowest track # %d ::  highest track # %d",dinfo.low_track,dinfo.hi_track );
  779.     
  780.     ReportMsg( mRequests[rIDISKINFO],"Lead out RedBook address = " );
  781.     PrintRed (dinfo.start);
  782.  
  783.     ReportMsg( mRequests[rITNOINFO],"" );
  784.  
  785.     //
  786.     // Read the track information and do a seek to each track
  787.     //
  788.     for ( i=dinfo.low_track; i <= dinfo.hi_track ; i++ ) 
  789.     {
  790.         wStatus=WDvRqIoiTnoInfo( drv,i,&tno );
  791.         printf("\n");
  792.         InterpStatus(wStatus);
  793.             
  794.         if ( !(ERRORBIT&ErrorTest( wStatus,mRequests[rITNOINFO] )) )
  795.         {
  796.  
  797.             printf( "\tTrack # %d ",i);
  798.             PrintRed(tno.start_tno);
  799.             printf( " \tControl Info %.2x",tno.tcntrl);
  800.         }
  801.     }
  802.  
  803.     ReportMsg( mRequests[rPLAY],"Track " );
  804.     printf( "%d",dinfo.low_track );
  805.  
  806.     //
  807.     // Find the lowest track address and begin playing
  808.     //
  809.  
  810.     StatusTest( wStatus,WDvRqIoiTnoInfo( drv,dinfo.low_track,&tno ),
  811.         mRequests[rITNOINFO] );
  812.             
  813.     if ( ERRORBIT&ErrorTest( wStatus,mRequests[rITNOINFO] ) )
  814.     {
  815.         WarningMsg( mRequests[rIDISKINFO],"Skipping Track Info Requests" );
  816.         WarningMsg( mRequests[rITNOINFO],"Skipping Play, Stop, Resume requests" );
  817.         return;
  818.     }
  819.  
  820. // First track specfied in testdrv.pro 
  821. // Keep this option open too thru a boolean flag in testdrv.pro
  822.  
  823.    StatusTest( wStatus,WDvRqPlay( drv,mplRedSector[0],red2hsg(RedDiff( mplRedSector[0], dinfo.start )),REDBOOK_ADDRMODE ),mRequests[rPLAY] );
  824.  
  825.     if ( !(BUSYBIT&ErrorTest( wStatus,mRequests[rPLAY] )) )
  826.         ErrMsg( mRequests[rPLAY],"Does not return BUSY" );
  827.     else {
  828.    printf(" \nPlaying track from "); PrintRed(mplRedSector[0]) ;
  829.    }
  830.     
  831.     //
  832.     // For now, try to read 10 sectors worth of sub channel information
  833.     //
  834.  
  835.     // This ioctl is generally useful during an AUDIO play request
  836.     // We expect the info to be delivered in real time
  837.         
  838.     if ( fSubInfo )
  839.         TestSubInfo ( drv, tno.start_tno, 10 );
  840.         
  841.     //
  842.     // Query if the music is playing.
  843.     // 
  844.         
  845.     if ( fInteract )
  846.     {
  847.         if ( Ask( "Can you hear music playing" ) )
  848.             ReportMsg( mRequests[rPLAY],"Request Completed Sucessfully." );
  849.         else
  850.             WarningMsg( mRequests[rPLAY],"No Audio Response" );
  851.     }
  852.  
  853.     //
  854.     // Short Testing loop for the Qchannel
  855.     //     
  856.     
  857.       // Track info is returned in hex  
  858.     for ( i=1;i<=5;i++ ) 
  859.     {
  860.    printf("\n=======================================================================");
  861.    printf("\n\t Q Channel Sample #%d\n",i); 
  862.    if (fInteract){
  863.       printf("Note the statistics when head is moving \n");
  864.       printf("Press any key to proceed ....\n");
  865.       getch();
  866.    }
  867.  
  868.         StatusTest( wStatus,WDvRqIoiQinfo( drv,&qinfo ),mRequests[rIQINFO] );
  869.         if ( ERRORBIT&ErrorTest( wStatus,mRequests[rIQINFO] ) )
  870.             break;
  871.         
  872.         StatusTest( wStatus,WDvRqIoiLocHead( drv,REDBOOK_ADDRMODE,&loc ),
  873.             mRequests[rILOCHEAD] );
  874.         if ( ERRORBIT&ErrorTest( wStatus,mRequests[rILOCHEAD] ) )
  875.             break;
  876.         
  877.        printf( "\n #%d Qinfo: Cntrl %d, Track %x, P/Index %d, Track Running Time %d:%d:%d\nDisk running time: %d:%d:%d",i,
  878.             qinfo.ctrl,qinfo.tno,qinfo.x,qinfo.min,qinfo.sec,qinfo.frame,qinfo.pmin,
  879.             qinfo.psec,qinfo.pframe );
  880.             printf( "\nLocation of Head " );PrintRed(loc);
  881.     }
  882.  
  883.     //
  884.     // Attempt Audio Control Testing
  885.     //
  886.         
  887.     if ( fAudCtrl )
  888.         TestAudioCtrl( drv );
  889.  
  890.  
  891.     if ( fInteract && Ask( "Test Stop and Pause" ) )
  892.     {
  893.         //
  894.         // test pause
  895.         //
  896.             
  897.         ReportMsg( mRequests[rSTOP],"Pausing" );
  898.  
  899.         StatusTest( wStatus,WDvRqStop( drv ),mRequests[rSTOP] );
  900.         ErrorTest( wStatus,mRequests[rSTOP] );
  901.         
  902.         StatusTest( wStatus,WDvRqIoiAudStat( drv,&audstatRec ),
  903.             mRequests[rIAUDSTAT] );
  904.         ErrorTest( wStatus,mRequests[rIAUDSTAT] );
  905.  
  906.         if ( !Ask( "Did the music pause" ) )
  907.             ErrMsg( mRequests[rSTOP],"Fails to pause" );
  908.         
  909.         if ( !(ERRORBIT&wStatus) )
  910.         {
  911.             if ( audstatRec.stat_bits&AUDIO_PAUSEDBIT )
  912.                 ReportMsg( mRequests[rSTOP],"PAUSED Correctly" );
  913.             else
  914.                 ErrMsg( mRequests[rSTOP],"Failed to pause" );
  915.         }
  916.             
  917.         ReportMsg( mRequests[rRESUME],"" );
  918.         
  919.         StatusTest( wStatus,WDvRqResume( drv ),mRequests[rRESUME] );
  920.         ErrorTest( wStatus,mRequests[rRESUME] );
  921.         
  922.         if ( !Ask("Did the music resume" ) )
  923.             ErrMsg( mRequests[rRESUME],"Did not resume" );
  924.  
  925.         StatusTest( wStatus,WDvRqResume( drv ),mRequests[rRESUME] );
  926.         
  927.         if ( !(ERRORBIT&wStatus) )
  928.             ErrMsg( mRequests[rRESUME],"Second Call to Resume did not return in error" );
  929.  
  930.         //
  931.         // Test Pause again
  932.         //
  933.             
  934.         ReportMsg( mRequests[rSTOP],"Pausing" );
  935.  
  936.         StatusTest( wStatus,WDvRqStop( drv ),mRequests[rSTOP] );    
  937.         ErrorTest( wStatus,mRequests[rSTOP] );
  938.         
  939.         StatusTest( wStatus,WDvRqIoiAudStat( drv,&audstatRec ),
  940.             mRequests[rIAUDSTAT] );
  941.         
  942.         if ( !(ERRORBIT&ErrorTest( wStatus,mRequests[rIAUDSTAT] )) )
  943.         {   
  944.             if ( audstatRec.stat_bits&AUDIO_PAUSEDBIT )
  945.                 ReportMsg( mRequests[rSTOP],"PAUSED Correctly" );
  946.             else
  947.                 ErrMsg( mRequests[rSTOP],"Failed to pause" );
  948.         }   
  949.  
  950.         //
  951.         // Test Stop
  952.         // 
  953.  
  954.         ReportMsg( mRequests[rSTOP],"" );
  955.         
  956.         StatusTest( wStatus,WDvRqStop( drv ),mRequests[rSTOP] );
  957.         ErrorTest( wStatus,mRequests[rSTOP] );    
  958.     
  959.         StatusTest( wStatus,WDvRqIoiAudStat( drv,&audstatRec ),
  960.             mRequests[rIAUDSTAT] );
  961.             
  962.         if ( !(ERRORBIT&ErrorTest( wStatus,mRequests[rIAUDSTAT] )) )
  963.         {
  964.             if ( audstatRec.stat_bits&AUDIO_PAUSEDBIT )
  965.                 ErrMsg( mRequests[rSTOP],"Failed to stop" );
  966.             else if ( audstatRec.start_tno != 0 && audstatRec.end_tno != 0 )
  967.                 ErrMsg( mRequests[rSTOP],"Failed to reset pause statistics" );
  968.         }   
  969.     }
  970.     
  971.     //
  972.     // Make sure its stopped
  973.     //
  974.         
  975.     WDvRqStop(drv);
  976.     printf( "\n\n[End of Audio Tests]" );
  977.         
  978. }
  979. /*
  980. ** void TestSubInfo(Dev_List *, DWORD, DWORD)
  981. ** - Dump Sub Channel Information.
  982. */ 
  983. // The idea is to take a RedBook address of a particular 
  984. // sector/frame and copy the sub channel info for each 
  985. // to the txf address . For multiple sectors copy info
  986. // sequentially (96 bytes /sector)
  987.  
  988. void TestSubInfo(drv,dwAddr,dwNum)
  989. DWORD dwAddr, dwNum;
  990. Dev_List * drv;
  991. {
  992.     extern FLAG fVerbose, fSubInfo;
  993.     BYTE _far * xfer;
  994.     WORD wStatus;
  995.     
  996.     if (xfer = (BYTE _far *) my_malloc ((WORD)dwNum * 96))
  997.     {
  998.         StatusTest (wStatus,WDvRqIoiSubChInfo(drv,dwAddr,xfer,dwNum),
  999.             mRequests[rISUBINFO]);
  1000.         if (fSubInfo)
  1001.         {
  1002.             if (!(ERRORBIT&wStatus))
  1003.             {
  1004.                 ReportMsg(mRequests[rISUBINFO],"Sub Channel Info returned:");
  1005.                 HexDump( xfer, (WORD)dwNum*96 );
  1006.             }
  1007.             else 
  1008.                 ErrorTest(wStatus,mRequests[rISUBINFO]);
  1009.         }
  1010.         else if (!(ERRORBIT&wStatus))
  1011.             ErrMsg(mRequests[rISUBINFO],"No Error Returned.");
  1012.         else if (!(UNKNOWN_CMD&wStatus))
  1013.             ErrMsg(mRequests[rISUBINFO],"Does not return UNKNOWN COMMAND");
  1014.     }
  1015.     
  1016.     if (xfer)
  1017.         my_free(xfer);
  1018. }
  1019.  
  1020.  
  1021. /*
  1022. ** void TestEject(Dev_List *)
  1023. **
  1024. */
  1025. void TestEject( drv )
  1026. Dev_List * drv;
  1027. {   
  1028.     extern FLAG fEject, fInteract, fVerbose, fAudio, fPrefetch;
  1029.     extern WORD cwSkipped;
  1030.     
  1031.     char chMedChng;
  1032.     WORD wStatus;
  1033.     DWORD lStatWord;
  1034.     BYTE _far * lpbBuf;
  1035.  
  1036.     // Eject Testing
  1037.     // Most drives allow ejecting, though many use the disc
  1038.     // caddy and cannot return.  This must be an attended
  1039.     // operation.
  1040.  
  1041.     printf( "\n\n[EJECT TEST]\n" );
  1042.  
  1043.     if ( !fEject )
  1044.     {
  1045.         StatusTest( wStatus, WDvRqIooEject( drv ),mRequests[rOEJECT] );
  1046.         if ( !(wStatus&(UNKNOWN_CMD|ERRORBIT)) )
  1047.             ErrMsg( mRequests[rOEJECT],
  1048.                 "Driver does not return UNKNOWN COMMAND" );
  1049.     }
  1050.     else if ( Ask( szLocalMsgs[1] ) ) 
  1051.     {
  1052.  
  1053.         StatusTest( wStatus,WDvRqIooEject( drv ),mRequests[rOEJECT] );
  1054.         ErrorTest( wStatus,mRequests[rOEJECT] );
  1055.  
  1056.         if ( Ask( "Did the Disk Eject" ) )
  1057.             ReportMsg( mRequests[rOEJECT],"Correctly Ejects disk." );
  1058.         else
  1059.         {
  1060.             ErrMsg( mRequests[rOEJECT],"Failure" );
  1061.             printf( "\n\t\tPlease MANUALLY eject the disk" );
  1062.             printf( "\n\t\tPress any key." );
  1063.             getch();
  1064.         }
  1065.  
  1066.         StatusTest( wStatus,WDvRqIoiDevStat( drv,&lStatWord ),
  1067.             mRequests[rIDEVSTAT] );
  1068.         ErrorTest( wStatus,mRequests[rIDEVSTAT] );
  1069.  
  1070.         if ( !(lStatWord&DEVSTAT_NODISK) )
  1071.             ErrMsg( mRequests[rIDEVSTAT],
  1072.                 "Driver still detects a disk is in the drive" );
  1073.         //
  1074.         // Test the MediaChanged byte
  1075.         //
  1076.             
  1077.         ReportMsg( mRequests[rIMEDCHNG],"" );
  1078.         
  1079.         if ( Ask( szLocalMsgs[0] ) )
  1080.         {
  1081.             StatusTest( wStatus,WDvRqIoiMedChng( drv,&chMedChng ),
  1082.                 mRequests[rIMEDCHNG] );
  1083.             ErrorTest( wStatus,mRequests[rIMEDCHNG] );
  1084.  
  1085.             switch ( chMedChng )
  1086.             {
  1087.                 case 1:
  1088.                     ErrMsg( mRequests[rIMEDCHNG],"Still thinks Media Not Changed" );
  1089.                     break;
  1090.                 case 0:
  1091.                     WarningMsg( mRequests[rIMEDCHNG],"Does not know if Media Changed" );
  1092.                     break;
  1093.                 case -1:
  1094.                     ReportMsg( mRequests[rIMEDCHNG],"Reports Media Changed" );
  1095.                     break;
  1096.                 default:
  1097.                     ErrMsg( mRequests[rIMEDCHNG],"Call returns a value not 1,0,-1" );
  1098.                     break;
  1099.             }
  1100.         }
  1101.         else cwSkipped++;
  1102.  
  1103.         {       
  1104.             //
  1105.             // Attempt a ReadL, ReadLPre, Play, Seek on an open drive.
  1106.             //
  1107.                 
  1108.             extern FLAG fInteract;
  1109.             extern time_t time(time_t *);
  1110.             time_t cTimeStart,cTimeFinish;
  1111.             DWORD vsize;
  1112.             
  1113.             if ( Ask( "Test ReadL on an open drive" ) )
  1114.             {
  1115.                 
  1116.                 lpbBuf = my_malloc( (size_t)RAW_SECTOR_SIZE );         
  1117.             
  1118.                 ReportMsg( mRequests[rREADL],"Testing Read on open drive" );
  1119.     
  1120.                 time( &cTimeStart );
  1121.  
  1122.                 StatusTest( wStatus,WDvRqReadL( drv,(BYTE _far *)lpbBuf,0L,
  1123.                     (WORD)1,HSG_ADDRMODE,COOKED_MODE,0,0 ),mRequests[rREADL] );
  1124.                 if ( !((ERRORBIT|DONEBIT|DRV_NOT_READY)&wStatus) )
  1125.                     ErrMsg( mRequests[rREADL],
  1126.                         "Does not return DRIVE NOT READY error" );
  1127.                 time( &cTimeFinish );
  1128.                 printf( "\n\t\tTimeout took: %ld sec",cTimeFinish-cTimeStart );
  1129.                 my_free( lpbBuf );
  1130.             }
  1131.             else cwSkipped++;
  1132.  
  1133.             if ( fPrefetch && Ask( "Test ReadLPre on an open drive" ) )
  1134.             {
  1135.                 StatusTest( wStatus,WDvRqReadLPre( drv,0L,(WORD)1,
  1136.                     HSG_ADDRMODE,COOKED_MODE,0,0 ),mRequests[rREADLPRE] );
  1137.                 
  1138.                 if ( !((ERRORBIT|DONEBIT|DRV_NOT_READY)&wStatus) )
  1139.                     ErrMsg( mRequests[rREADLPRE],
  1140.                         szLocalMsgs[2]);
  1141.             }
  1142.             else cwSkipped++;
  1143.             
  1144.             if ( Ask( "Test IOCTLI:VolSize on an open drive" ) )
  1145.             {
  1146.                 StatusTest( wStatus,WDvRqIoiVolSize( drv, &vsize ),
  1147.                     mRequests[rIVOLSIZE] );
  1148.                 if ( !((ERRORBIT|DONEBIT|DRV_NOT_READY)&wStatus) )
  1149.                     ErrMsg( mRequests[rIVOLSIZE], szLocalMsgs[2] );
  1150.             }
  1151.                         
  1152.             if ( Ask( "Test Seek on an open drive" ) )
  1153.             {
  1154.                 StatusTest( wStatus,WDvRqSeek( drv,0L,HSG_ADDRMODE ),
  1155.                     mRequests[rSEEK] );
  1156.                 if ( !((ERRORBIT|DONEBIT|DRV_NOT_READY)&wStatus) )
  1157.                     ErrMsg( mRequests[rSEEK],
  1158.                         szLocalMsgs[2]);
  1159.             }
  1160.             else cwSkipped++;
  1161.             
  1162.             if ( fAudio && Ask( "Test Play on an open drive" ) )
  1163.             {
  1164.                 StatusTest( wStatus,WDvRqPlay( drv,0L,0x0000ffff,
  1165.                     HSG_ADDRMODE ),mRequests[rPLAY] );
  1166.                 if ( !((ERRORBIT|DONEBIT|DRV_NOT_READY)&wStatus) )
  1167.                     ErrMsg( mRequests[rPLAY],
  1168.                         szLocalMsgs[2]);
  1169.             }
  1170.             else cwSkipped++;
  1171.             
  1172.         }
  1173.     
  1174.         StatusTest( wStatus,WDvRqIooCloseTray( drv ),mRequests[rOCLOSETRAY] );
  1175.         ErrorTest( wStatus,mRequests[rOCLOSETRAY] );
  1176.  
  1177.         if ( Ask( "Did the Disk Close" ) )
  1178.             ReportMsg( mRequests[rOCLOSETRAY],"Correctly Closes Tray." );
  1179.         else
  1180.         {
  1181.             WarningMsg( mRequests[rOCLOSETRAY],"Cannot Close Tray." );
  1182.             printf( "\n\t\tPlease manually close the tray" );
  1183.             printf( "\n\t\tPress any key when closed." );
  1184.             getch();
  1185.         }
  1186.  
  1187.         StatusTest( wStatus,WDvRqIoiDevStat( drv,&lStatWord ),
  1188.             mRequests[rIDEVSTAT] );
  1189.         ErrorTest( wStatus,mRequests[rIDEVSTAT] );
  1190.                 
  1191.         if ( lStatWord&DEVSTAT_NODISK )
  1192.             ErrMsg( mRequests[rIDEVSTAT],"Unable to detect a disk in the drive" );
  1193.     }
  1194.     printf( "\n\n[End of EJECT TEST]\n" );
  1195. }
  1196.  
  1197. /*
  1198. ** WORD TestRead(Dev_List *,DWORD,BYTE,BYTE,char _far *)
  1199. **
  1200. */
  1201.  
  1202. WORD TestRead( drv,lSector,bAddrMode,bReadMode,lpInBuf )
  1203. Dev_List * drv;
  1204. DWORD lSector;
  1205. BYTE bAddrMode,bReadMode;
  1206. BYTE _far * lpInBuf;
  1207. {
  1208.     extern BYTE bInterSize,bInterSkip;
  1209.     extern FLAG fVerbose,fInterleave,fPrefetch;
  1210.     
  1211.     WORD wStatus;
  1212.  
  1213.     if (fPrefetch)
  1214.     {   
  1215.         if ( fInterleave )
  1216.         {
  1217.             StatusTest( wStatus,WDvRqReadLPre( drv,lSector,1,bAddrMode,
  1218.                 bReadMode,bInterSize,bInterSkip ),mRequests[rREADLPRE] );
  1219.         }
  1220.         else
  1221.         {
  1222.             StatusTest( wStatus,WDvRqReadLPre( drv,lSector,1,bAddrMode,
  1223.                 bReadMode,0x0,0x0 ),mRequests[rREADLPRE] );
  1224.         }
  1225.         ErrorTest( wStatus,mRequests[rREADLPRE] );
  1226.     }
  1227.     
  1228.  
  1229.  
  1230.     if ( fInterleave )
  1231.     {
  1232.         StatusTest( wStatus,WDvRqReadL( drv,(BYTE _far *)lpInBuf,lSector,1,
  1233.             bAddrMode,bReadMode,bInterSize,bInterSkip ),mRequests[rREADL] );
  1234.     }
  1235.     else
  1236.     {
  1237.         StatusTest( wStatus,WDvRqReadL( drv,(BYTE _far *)lpInBuf,lSector,1,
  1238.             bAddrMode,bReadMode,0x0,0x0 ),mRequests[rREADL] );
  1239.     }
  1240.     
  1241.     ErrorTest( wStatus,mRequests[rREADL] );
  1242.     return wStatus;
  1243. }
  1244.  
  1245. /*
  1246. ** TestControl(Dev_List *)
  1247. ** - verifies correctness of disk information against
  1248. **   control data
  1249. **
  1250. */
  1251.  
  1252. void TestControl( drv )
  1253. Dev_List    * drv;
  1254. {
  1255.     extern FLAG fInteract,fUPC,fVerbose,fRaw;
  1256.     extern char * szStdPath;
  1257.     extern WORD wDriveNum;
  1258.         
  1259.     BYTE _far * lpbArcBuf;      // Archive Buffer
  1260.     BYTE _far * lpbDiscBuf;     // Disc Read Buffer
  1261.  
  1262.     char szDiskTitle[256],szFullPath[256],len;
  1263.     char szArcVolLabel[13],szDiskVolLabel[13];
  1264.     
  1265.     DWORD   lSector,vsizeDisc,vsizeArc;
  1266.     BYTE    bEquiv,fVolErr,fUPCErr,iTrack,bAddrMode,bReadMode;
  1267.     WORD    iArc,wStatus,wNum;
  1268.     int     fh;                 // file handle to the Archive file
  1269.  
  1270.     UPCCode_Rec upcDisc,upcArc;
  1271.     DiskInfo_Rec    dinfoDisc,dinfoArc;
  1272.     TnoInfo_Rec tinfoDisc,tinfoArc;
  1273.  
  1274.     printf( "\n\n[SECTOR MATCHING TESTS]\n" );
  1275.     
  1276.  
  1277.     if ( fInteract && !Ask( szLocalMsgs[1] ) )
  1278.         return;
  1279.  
  1280.     //
  1281.     // Try to get a VOLUME SIZE
  1282.     //
  1283.  
  1284.     StatusTest( wStatus,WDvRqIoiVolSize( drv,&vsizeDisc ),
  1285.         mRequests[rIVOLSIZE] );
  1286.  
  1287.     if ( ERRORBIT&wStatus )
  1288.     {
  1289.         fVolErr = TRUE;
  1290.         ErrorTest( wStatus,mRequests[rIVOLSIZE] );
  1291.     }
  1292.     else
  1293.     {
  1294.         fVolErr = FALSE;
  1295.         if ( fVerbose )
  1296.         {
  1297.             ReportMsg( mRequests[rIVOLSIZE], "Volume Size = ");
  1298.             printf( "%lu",vsizeDisc);
  1299.         }
  1300.     }
  1301.     
  1302.     //
  1303.     // Try to get a UPC code
  1304.     //
  1305.         
  1306.     if ( fUPC ) 
  1307.     {
  1308.         StatusTest( wStatus,WDvRqIoiUPCCode( drv,&upcDisc ),
  1309.             mRequests[rIUPCCODE] );
  1310.     
  1311.         if ( ERRORBIT&wStatus )
  1312.         {
  1313.             fUPCErr = TRUE;
  1314.             ErrorTest( wStatus,mRequests[rIUPCCODE] );
  1315.         }
  1316.         else
  1317.             fUPCErr = FALSE;
  1318.     }
  1319.     else
  1320.         fUPCErr = TRUE;
  1321.  
  1322.     //
  1323.     // Try to get the VTOC information
  1324.     //
  1325.     
  1326.     StatusTest( wStatus,WDvRqIoiDiskInfo( drv,&dinfoDisc ),
  1327.         mRequests[rIDISKINFO] );
  1328.     ErrorTest( wStatus,mRequests[rIDISKINFO] );
  1329.     
  1330.     if ( ERRORBIT&wStatus )
  1331.     {
  1332.         ErrMsg( mRequests[rIDISKINFO],"Insufficient Disk Information to continue" );
  1333.         ReportMsg( mRequests[rIDISKINFO],"Falling through to plain Sector Dump" );
  1334.         SectorDump( drv ); 
  1335.         return;
  1336.     }
  1337.  
  1338.     // Identify the archive or call hex dump
  1339.     // Assumption: if a structure from the archive has a
  1340.     //  code field == 0, the call that relates the structure
  1341.     //  was unsupported on archive creation.
  1342.  
  1343.     lpbArcBuf = my_malloc( (size_t)RAW_SECTOR_SIZE );
  1344.     lpbDiscBuf = my_malloc( (size_t)RAW_SECTOR_SIZE );
  1345.  
  1346. // This is the place where the four .bin files are being
  1347. // read in .testdrv assumes that there is always a 
  1348. // Bookshelf .Make this feature interactive ..
  1349. // Ask the user , if Yes , then read in 4 files etc 
  1350.  
  1351.     for( iArc=0;iArc<NUM_ARCHIVES;iArc++,bEquiv=FALSE )
  1352.  
  1353.     {
  1354.         if ( szStdPath )
  1355.             sprintf( szFullPath,"%s\\%s",szStdPath,szArc[iArc] );
  1356.         else
  1357.             sprintf( szFullPath,"%s",szArc[iArc] );
  1358.         
  1359.         printf( "\nTesting %s\n",szFullPath );
  1360.         
  1361.         if ( _dos_open( szFullPath,O_RDONLY, &fh ) == 0 ) 
  1362.         {
  1363.             _dos_read(fh,&len,1,&wNum);
  1364.             _dos_read(fh,szDiskTitle,len,&wNum);
  1365.             _dos_read(fh,&upcArc,sizeof(UPCCode_Rec),&wNum);
  1366.             _dos_read(fh,&dinfoArc,sizeof( DiskInfo_Rec ),&wNum);
  1367.             _dos_read(fh,&vsizeArc,sizeof(DWORD),&wNum);
  1368.             _dos_read(fh,szArcVolLabel,13,&wNum);
  1369.  
  1370.             if ( fVerbose )
  1371.             {
  1372.                 printf( "\nArchive Volume Size = %lu ",vsizeArc );
  1373.                 printf( "\nArchive Volume Label = %s \n",szArcVolLabel );
  1374.             }
  1375.             
  1376.             if ( !strcmp( szArcVolLabel, szDiskVolLabel ) )
  1377.             {
  1378.                 bEquiv = TRUE;
  1379.  
  1380.                 if ( (dinfoArc.low_track != dinfoDisc.low_track) ||
  1381.                     (dinfoArc.hi_track != dinfoDisc.hi_track) ||
  1382.                     (dinfoArc.start != dinfoDisc.start) )
  1383.                 {
  1384.                     bEquiv = FALSE;
  1385.                     if (fVerbose)
  1386.                         printf ( "\nFailed VTOC Check" );
  1387.                 }
  1388.  
  1389.                 if ( !fVolErr && vsizeArc != 0 && vsizeArc != vsizeDisc )
  1390.                 {
  1391.                     bEquiv = FALSE;
  1392.                     if (fVerbose)
  1393.                         printf ( "\nFailed Volume Size Check" );
  1394.                 }
  1395.                 
  1396.                 if ( fUPC && upcArc.code != 0 && !fUPCErr )
  1397.                 {
  1398.                     if ( !((memcmp( upcArc.upc,upcDisc.upc,7 ) == 0) &&
  1399.                         (upcArc.aframe == upcDisc.aframe)&&
  1400.                         (upcArc.ctrl_adr == upcDisc.ctrl_adr)) )
  1401.                     {
  1402.                         bEquiv = FALSE;
  1403.                         if (fVerbose)
  1404.                             printf( "\nFailed UPC check" );
  1405.                     }
  1406.                 }
  1407.                 
  1408.                 if ( bEquiv ) break;
  1409.             }
  1410.         }
  1411.         else
  1412.             printf( "***WARNING***\tControl File \"%s\" Not Found, skipping.\n",
  1413.                 szFullPath );
  1414.     }
  1415.  
  1416.     if ( !bEquiv )
  1417.     {
  1418.         my_free(lpbArcBuf);
  1419.         my_free(lpbDiscBuf);
  1420.         return ( SectorDump( drv ) );
  1421.     }
  1422.  
  1423.     szDiskTitle[len] = '\0';
  1424.     printf( "\nMatching Archive Found: %s\n",szDiskTitle );
  1425.  
  1426.     // The archive file consists of:
  1427.     // [Strlen(title)   char        ]
  1428.     // [Title       char[]      ]
  1429.     // [UPCCode     UPCCode_Rec ]
  1430.     // [DiskInfo        DiskInfo_Rec    ]
  1431.     // [Volsize     DWORD       ]
  1432.     // [TrackInfo       TnoInfo_Rec ]+
  1433.     // [DATABLOCK       [AddrMode char]
  1434.     //          [Sector   long]
  1435.     //          [ReadMode char]
  1436.     //          [SectorData char[]]]+
  1437.     //
  1438.     
  1439.     for ( iTrack=dinfoArc.low_track;
  1440.           iTrack<=dinfoArc.hi_track;
  1441.           iTrack++ )
  1442.     {
  1443.         WDvRqIoiTnoInfo( drv,iTrack,&tinfoDisc );
  1444.         _dos_read(fh,&tinfoArc,sizeof(TnoInfo_Rec),&wNum);
  1445.         if ( tinfoDisc.tno != tinfoArc.tno ||
  1446.             tinfoDisc.start_tno != tinfoArc.start_tno ||
  1447.             tinfoDisc.tcntrl != tinfoArc.tcntrl )
  1448.             WarningMsg(mRequests[rITNOINFO],"Track information does not match" );
  1449.     }
  1450.     //
  1451.     // Read Sector 0 information
  1452.     //
  1453.     _dos_read( fh,&bAddrMode,1,&wNum );
  1454.     _dos_read( fh,&lSector,sizeof(DWORD),&wNum );
  1455.     _dos_read( fh,&bReadMode,1,&wNum );
  1456.     _dos_read( fh,lpbArcBuf,COOKED_SECTOR_SIZE,&wNum );
  1457.  
  1458.     TestRead( drv,lSector,bAddrMode,bReadMode,lpbDiscBuf );
  1459.  
  1460.     if (_fmemcmp( lpbArcBuf,lpbDiscBuf,COOKED_SECTOR_SIZE ) )
  1461.     {
  1462.         WarningMsg(mRequests[rREADL],"Sector 0 comparison failed" );
  1463.     }
  1464.                     
  1465.     //
  1466.     // Sector Read Tests
  1467.     //
  1468.  
  1469.     while ( TRUE )
  1470.     {
  1471.         
  1472.         
  1473.         if ( _dos_read( fh, &bAddrMode,1,&wNum ) != 0)
  1474.         {
  1475.             my_free( lpbDiscBuf );
  1476.             my_free( lpbArcBuf );
  1477.             return;
  1478.         }
  1479.         else if (wNum == 0)
  1480.             break;
  1481.         
  1482.         if ( bAddrMode == REDBOOK_ADDRMODE )
  1483.             printf( "\nRedbook Addressing, " );
  1484.         else if ( bAddrMode == HSG_ADDRMODE )
  1485.             printf( "\nHSG Addressing, " );
  1486.         else
  1487.             fatalError( "DISK READ ERROR, Exiting." );
  1488.  
  1489.         _dos_read(fh,&lSector,sizeof(DWORD),&wNum);
  1490.         
  1491.         printf( "Sector %lx, ",lSector );
  1492.  
  1493.         _dos_read( fh,&bReadMode,1,&wNum);
  1494.         
  1495.         if ( bReadMode == COOKED_MODE )
  1496.             printf( "Cooked\n" );
  1497.         else if ( bReadMode == RAW_MODE )
  1498.             printf( "Raw\n" );
  1499.         else 
  1500.             fatalError( "DISK READ ERROR, Exiting." );
  1501.         
  1502.         if ( bReadMode == COOKED_MODE )
  1503.             _dos_read( fh,lpbArcBuf,COOKED_SECTOR_SIZE,&wNum );
  1504.         else if ( bReadMode == RAW_MODE )
  1505.             _dos_read( fh,lpbArcBuf,RAW_SECTOR_SIZE,&wNum );
  1506.         else
  1507.             fatalError( "Error Reading File, Exiting." );
  1508.  
  1509.         if ( !(ERRORBIT & TestRead( drv,lSector,bAddrMode,bReadMode,
  1510.             lpbDiscBuf )) )
  1511.         {
  1512.             if ( bReadMode==COOKED_MODE )
  1513.             {
  1514.                 if ( _fmemcmp( lpbArcBuf,lpbDiscBuf,COOKED_SECTOR_SIZE ) )
  1515.                 {
  1516.                     WarningMsg( mRequests[rREADL],"Cooked Comparison Differs" );
  1517.                     if ( fVerbose ) 
  1518.                     {
  1519.                         printf( "\nDisc information\n" );
  1520.                         HexDump( lpbDiscBuf,COOKED_SECTOR_SIZE );
  1521.                         printf( "Archive information \n" );
  1522.                         HexDump( lpbArcBuf,COOKED_SECTOR_SIZE );
  1523.                     }
  1524.                 }
  1525.             }
  1526.             else if ( fRaw )
  1527.             {
  1528.                 if ( _fmemcmp( lpbArcBuf,lpbDiscBuf,RAW_SECTOR_SIZE ) )
  1529.                 {
  1530.                     WarningMsg( mRequests[rREADL],"Raw Comparison Differs" );
  1531.                     if ( fVerbose ) 
  1532.                     {
  1533.                         printf( "\nDisc information\n" );
  1534.                         HexDump( lpbDiscBuf,COOKED_SECTOR_SIZE );
  1535.                         printf( "Archive information \n" );
  1536.                         HexDump( lpbArcBuf,COOKED_SECTOR_SIZE );
  1537.                     }
  1538.                 }
  1539.             }
  1540.         }
  1541.     }
  1542.     my_free( lpbDiscBuf );
  1543.     my_free( lpbArcBuf );
  1544.     
  1545.     _dos_close( fh );
  1546.     printf( "\n\n[End of SECTOR MATCHING TESTS]\n" );
  1547. }
  1548.     
  1549.  
  1550. /*
  1551. ** SectorDump( Dev_List *)
  1552. ** - dumps all sectors in HSG and Redbook format specified in the
  1553. **   profile.
  1554. */
  1555. void    SectorDump( drv )
  1556. Dev_List    * drv;
  1557. {
  1558.     extern WORD cwHSGSectors,cwRedSectors;
  1559.     extern DWORD mplHSGSector[],mplRedSector[];
  1560.     extern BYTE bInterSize, bInterSkip;
  1561.     extern FLAG  fVerbose,fInteract,fRaw;
  1562.     WORD iSector,wStatus;
  1563.     char _far * lpbDiscBuf;
  1564.     
  1565.     printf( "\n\n[Sector Dump]\n" );
  1566.     if ( fInteract && !Ask( "Attempt sector dumps" ) )
  1567.         return;
  1568.     
  1569.     lpbDiscBuf = my_malloc( (size_t)RAW_SECTOR_SIZE );
  1570.     
  1571.     for ( iSector=0;iSector<cwHSGSectors;iSector++ )
  1572.     {
  1573.         if ( fRaw && (!fInteract || Ask( "Read a RAW HSG Sector" )) )
  1574.         {
  1575.             wStatus = TestRead( drv,mplHSGSector[iSector],HSG_ADDRMODE,
  1576.                 RAW_MODE,lpbDiscBuf );
  1577.             if ( !(ERRORBIT&wStatus) )
  1578.             {
  1579.                 if ( fVerbose )
  1580.                 {
  1581.                     printf( "\nRaw dump of [HSG] Sector %0.8lx:",
  1582.                         mplHSGSector[iSector] );
  1583.                     HexDump( lpbDiscBuf,RAW_SECTOR_SIZE );
  1584.                 }
  1585.                 else printf( "\nRaw [HSG] Sector %0.8lx Read." );
  1586.             }
  1587.             else if ( DRV_NOT_READY&wStatus )
  1588.                 break;
  1589.                 
  1590.         }
  1591.         if ( !fInteract || Ask("Read a COOKED HSG Sector") )
  1592.         {
  1593.             wStatus = TestRead( drv,mplHSGSector[iSector],HSG_ADDRMODE,
  1594.                 COOKED_MODE,lpbDiscBuf );
  1595.             if ( !(ERRORBIT&wStatus) )
  1596.             {
  1597.                 if ( fVerbose )
  1598.                 {
  1599.                     printf( "\nCooked dump of [HSG] Sector %0.8lx:",
  1600.                         mplHSGSector[iSector] );
  1601.                     HexDump( lpbDiscBuf,COOKED_SECTOR_SIZE );
  1602.                 }
  1603.                 else printf( "\nCooked [HSG] Sector %0.8lx Read." );
  1604.             }
  1605.             else if ( DRV_NOT_READY&wStatus )
  1606.                 break;
  1607.         }
  1608.     }
  1609.     for ( iSector=0;iSector<cwRedSectors;iSector++ )
  1610.     {
  1611.         if ( fRaw && (!fInteract || Ask( "Read a RAW Redbook Sector" )) )
  1612.         {
  1613.             wStatus = TestRead( drv,mplRedSector[iSector],REDBOOK_ADDRMODE,
  1614.                 RAW_MODE,lpbDiscBuf );
  1615.             if ( !(ERRORBIT&wStatus) )
  1616.             {
  1617.                 if ( fVerbose )
  1618.                 {
  1619.                     printf( "\nRaw dump of [Redbook] Sector %0.8lx:",
  1620.                         mplRedSector[iSector] );
  1621.                     HexDump( lpbDiscBuf,RAW_SECTOR_SIZE );
  1622.                 }
  1623.                 else printf( "\nRaw [Redbook] Sector %0.8lx Read." );
  1624.             }
  1625.             else if ( DRV_NOT_READY&wStatus )
  1626.                 break;
  1627.         }
  1628.         if (!fInteract || Ask( "Read a COOKED Redbook Sector" ))
  1629.         {
  1630.             wStatus = TestRead( drv,mplRedSector[iSector],REDBOOK_ADDRMODE,
  1631.                 COOKED_MODE,lpbDiscBuf );
  1632.             if ( !(ERRORBIT&wStatus) )
  1633.             {
  1634.                 if ( fVerbose )
  1635.                 {
  1636.                     printf( "\nCooked dump of [Redbook] Sector %0.8lx:",
  1637.                         mplRedSector[iSector] );
  1638.                     HexDump( lpbDiscBuf,COOKED_SECTOR_SIZE );
  1639.                 }
  1640.                 else printf( "\nCooked [Redbook] Sector %0.8lx Read." );
  1641.             }
  1642.             else if ( DRV_NOT_READY&wStatus )
  1643.                 break;
  1644.         }
  1645.     }
  1646.     my_free( lpbDiscBuf );
  1647.     printf("\n\n[END SECTOR DUMP]\n");
  1648. }
  1649.  
  1650. /*
  1651. ** TestInit( Dev_List * )
  1652. ** - test driver call 0 INIT
  1653. */
  1654. void TestInit( drv )
  1655. Dev_List    *drv;
  1656. {
  1657.     extern FLAG fInteract, fVerbose;
  1658.     
  1659.     BYTE bEndAddr,bBPB;
  1660.     WORD wStatus;
  1661.     ReportMsg( mRequests[rINIT],"" );
  1662.  
  1663.     if ( !fInteract || Ask( "Test this request" ) )
  1664.     {
  1665.         StatusTest( wStatus,WDvRqInit( drv,&bEndAddr,&bBPB),
  1666.             mRequests[rINIT] );
  1667.     if ( !( (ERRORBIT & wStatus) && (SEC_INIT_ERR & wStatus)) )
  1668.             ErrMsg( mRequests[rINIT],"Does not return UNKNOWN COMMAND error" );
  1669.     }
  1670. }
  1671.  
  1672. /*
  1673. ** TestDevStat( Dev_List * )
  1674. ** - test DevStat return value 3:6
  1675. */
  1676. void TestDevStat( drv )
  1677. Dev_List    *drv;
  1678. {
  1679.     extern FLAG fRaw,fWriteMedia,fRedbook,fAudio,fInterleave,fPrefetch,
  1680.         fAudCtrl,fInteract,fVerbose,fSubInfo;
  1681.     DWORD lStatWord;
  1682.     WORD wStatus;
  1683.  
  1684.     static char * szMsgs [16] = {
  1685.         "Does not support raw mode",
  1686.         "Supports raw mode", 
  1687.         "Does not support writing",
  1688.         "Supports writing",
  1689.         "Does not support Redbook addressing",
  1690.         "Supports Redbook addressing",
  1691.         "Does not support audio",
  1692.         "Supports audio",
  1693.         "Does not support interleave",
  1694.         "Supports interleave",
  1695.         "Does not support prefetch",
  1696.         "Supports prefetch",
  1697.         "Does not support audio control",
  1698.         "Supports audio control",
  1699.         "Does not support R-W subchannels ",
  1700.         "Supports R-W subchannels "
  1701.     };
  1702.             
  1703.     ReportMsg( mRequests[rIDEVSTAT],"" );
  1704.     if ( fInteract && !Ask( szLocalMsgs[0] ) )
  1705.         return;
  1706.     
  1707.     StatusTest( wStatus,WDvRqIoiDevStat( drv,&lStatWord ),
  1708.         mRequests[rIDEVSTAT] );
  1709.     ErrorTest( wStatus,mRequests[rIDEVSTAT] );
  1710.  
  1711.     //
  1712.     // Test DevStat bits against the profile information
  1713.     // provided by: fRaw,fWriteMedia,fRedbook,fAudio,fInterleave,
  1714.     //      fPrefetch,fAudCtrl,fSubInfo
  1715.     //
  1716.     if (fVerbose)
  1717.     {
  1718.         ReportMsg(mRequests[rIDEVSTAT],"Returns StatusWord");
  1719.         printf("%0.8lX",lStatWord);
  1720.     }
  1721.  
  1722.     if ( EXOR( fRaw,lStatWord&DEVSTAT_RAW ) )
  1723.     {
  1724.         if ( fRaw )
  1725.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[0] );
  1726.         else
  1727.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[1] );
  1728.     }
  1729.     else if ( fVerbose )
  1730.     {
  1731.         if ( fRaw )
  1732.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[1] );
  1733.         else
  1734.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[0] );
  1735.     }
  1736.  
  1737.     
  1738.     if ( EXOR( fWriteMedia,lStatWord&DEVSTAT_WRITE ) )
  1739.     {
  1740.         if ( fWriteMedia )
  1741.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[2] );
  1742.         else
  1743.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[3] );
  1744.     }
  1745.     else if ( fVerbose )
  1746.     {
  1747.         if ( fWriteMedia )
  1748.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[3] );
  1749.         else
  1750.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[2] );
  1751.     }
  1752.  
  1753.     
  1754.     if ( EXOR( fRedbook,lStatWord&DEVSTAT_REDBOOK ) )
  1755.     {
  1756.         if ( fRedbook )
  1757.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[4] );
  1758.         else
  1759.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[5] );
  1760.     }
  1761.     else if ( fVerbose )
  1762.     {
  1763.         if ( fRedbook )
  1764.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[5] );
  1765.         else
  1766.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[4] );
  1767.     }
  1768.  
  1769.     
  1770.     if ( EXOR( fAudio,lStatWord&DEVSTAT_AUDVID ) )
  1771.     {
  1772.         if ( fAudio )
  1773.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[6] );        
  1774.         else 
  1775.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[7] );        
  1776.     }
  1777.     else if (fVerbose)
  1778.     {
  1779.         if ( fAudio )
  1780.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[7] );
  1781.         else 
  1782.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[6] );        
  1783.     }
  1784.  
  1785.     
  1786.     if ( EXOR( fInterleave,lStatWord&DEVSTAT_INTERLEAVE ) )
  1787.     {
  1788.         if ( fInterleave )
  1789.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[8] );                
  1790.         else 
  1791.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[9] );                
  1792.     }
  1793.     else if (fVerbose)
  1794.     {
  1795.         if ( fInterleave )
  1796.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[9] );                
  1797.         else 
  1798.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[8] );        
  1799.             
  1800.     }
  1801.         
  1802.  
  1803.     if ( EXOR( fPrefetch,lStatWord&DEVSTAT_PREFETCH ) )
  1804.     {
  1805.         if ( fPrefetch )
  1806.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[10] );
  1807.         else 
  1808.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[11] );                        
  1809.    
  1810.     }
  1811.     else if (fVerbose)
  1812.     {
  1813.         if ( fPrefetch )
  1814.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[11] );                
  1815.         else 
  1816.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[10] );
  1817.     }
  1818.  
  1819.     
  1820.     if ( EXOR( fAudCtrl,lStatWord&DEVSTAT_AUDCTRL ) )
  1821.     {
  1822.         if ( fAudCtrl )
  1823.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[12] );
  1824.         else 
  1825.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[13] );
  1826.     }
  1827.     else if ( fVerbose )
  1828.     {
  1829.         if ( fAudCtrl )
  1830.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[13] );
  1831.         else 
  1832.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[12] );                
  1833.     }
  1834.  
  1835.     
  1836.     if ( EXOR ( fSubInfo,lStatWord&DEVSTAT_SUBINFO ) )
  1837.     {
  1838.         if ( fSubInfo )
  1839.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[14] );
  1840.         else
  1841.             ErrMsg( mRequests[rIDEVSTAT],szMsgs[15] );
  1842.     }
  1843.     else if ( fVerbose )
  1844.     {
  1845.         if ( fSubInfo )
  1846.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[15] );                
  1847.         else
  1848.             ReportMsg( mRequests[rIDEVSTAT],szMsgs[14] );
  1849.     }
  1850.     
  1851. }
  1852.  
  1853. /*
  1854. ** TestRaddr(Dev_List *)
  1855. ** - tests IOCTLI 3:0 Raddr
  1856. */
  1857.  
  1858. void TestRaddr( drv )
  1859. Dev_List *drv;
  1860. {
  1861.     extern WORD cwErrors;
  1862.     extern FLAG fInteract,fVerbose;
  1863.     WORD wStatus;
  1864.     DWORD lAddr;
  1865.  
  1866.     ReportMsg( mRequests[rIRADDR],"" );
  1867.     if ( !fInteract || Ask( szLocalMsgs[0] ) )
  1868.     {
  1869.         StatusTest( wStatus,WDvRqIoiRaddr( drv,&lAddr ),mRequests[rIRADDR] );
  1870.         if ( !(ERRORBIT&ErrorTest( wStatus,mRequests[rIRADDR] )) );
  1871.         {
  1872.             if ( (DWORD)(drv->dev_addr) == lAddr )
  1873.             {
  1874.                 ReportMsg( mRequests[rIRADDR],"Correctly Returns " );
  1875.                 printf( "0x%lx",lAddr );
  1876.             }
  1877.             else
  1878.             {
  1879.                 ReportMsg( mRequests[rIRADDR],"Incorrectly Returns " );
  1880.                 printf( "0x%lx",lAddr );
  1881.                 cwErrors++;
  1882.             }
  1883.         }
  1884.     }
  1885. }
  1886. /*
  1887. ** TestReset( Dev_List * )
  1888. ** - tests IOCTLO: 12.2 Reset
  1889. */
  1890. void TestReset( drv )
  1891. Dev_List *drv;
  1892. {
  1893.     extern FLAG fInteract, fVerbose;
  1894.     WORD wStatus;
  1895.     ReportMsg( mRequests[rORESET],"" );
  1896.     if ( !fInteract || Ask( szLocalMsgs[0] ) )
  1897.     {
  1898.         StatusTest( wStatus,WDvRqIooReset( drv ),mRequests[rORESET] );
  1899.         ErrorTest( wStatus,mRequests[rORESET] );
  1900.     }
  1901. }
  1902.  
  1903. /*
  1904. ** TestLockDoor( Dev_List * )
  1905. ** - tests IOCTLO: 12.1 LockDoor
  1906. */
  1907.  
  1908. /*
  1909. ** The tests can be altered to prompt the user to confirm that the door
  1910. ** is indeed locked.
  1911. */
  1912. void TestLockDoor( drv )
  1913. Dev_List * drv;
  1914. {
  1915.     extern FLAG fInteract, fVerbose;
  1916.     
  1917.     DWORD lStatWord,lOldState;
  1918.     WORD wStatus;
  1919.  
  1920.     ReportMsg( mRequests[rOLOCKDOOR],"" );
  1921.     
  1922.     if ( !fInteract || Ask( szLocalMsgs[1] ) )
  1923.     {
  1924.         
  1925.         StatusTest( wStatus,WDvRqIoiDevStat( drv,&lOldState ),mRequests[rIDEVSTAT] );
  1926.         ErrorTest( wStatus,mRequests[rIDEVSTAT] );
  1927.         
  1928.         if ( lOldState&DEVSTAT_DRLOCK )   
  1929.         {
  1930.             //
  1931.             // lock door if unlocked
  1932.             //
  1933.                 
  1934.             StatusTest( wStatus,WDvRqIooLockDoor( drv,LOCK_DOOR ),mRequests[rOLOCKDOOR] );
  1935.             ErrorTest( wStatus,mRequests[rOLOCKDOOR] );
  1936.         }
  1937.         else 
  1938.         {
  1939.             //
  1940.             // unlock door if locked
  1941.             //
  1942.                 
  1943.             StatusTest( wStatus,WDvRqIooLockDoor( drv,UNLOCK_DOOR ),
  1944.                 mRequests[rOLOCKDOOR] );
  1945.             ErrorTest( wStatus,mRequests[rOLOCKDOOR] );
  1946.         }
  1947.         StatusTest( wStatus,WDvRqIoiDevStat( drv,&lStatWord ),mRequests[rIDEVSTAT] );
  1948.     
  1949.         ErrorTest( wStatus,mRequests[rIDEVSTAT] );
  1950.  
  1951.         if ( (lStatWord&DEVSTAT_DRLOCK)==(lOldState&DEVSTAT_DRLOCK) )
  1952.             WarningMsg( mRequests[rOLOCKDOOR],"Unable to change Door State" );
  1953.  
  1954.         //
  1955.         // Try to make sure that the door is locked
  1956.         //
  1957.             
  1958.         StatusTest( wStatus,WDvRqIooLockDoor( drv,UNLOCK_DOOR ),mRequests[rOLOCKDOOR] );
  1959.         ErrorTest( wStatus,mRequests[rOLOCKDOOR] );
  1960.     }
  1961. }
  1962.